class Functor {
    constructor (value) {
        this._value = value;
    }
    static of(value) {
        return new Functor(value);
    }
    map(fn) {
        return Functor.of(fn(this._value));
    }
}

class Monad extends Functor {
    join() {
        return this._value;
    }
    flatMap(fn) {
        return this.map(fn).join();
    }
}

const fp = require('loadsh/fp');

class IO {
    constructor(fn) {
        this._value = fn;
    }
    static of(x) {
        return new IO(function() {
            return x;
        })
    }
    map(fn) {
        return new IO(fp.flowRight(fn, this._value));
    }
    join() {
        return this._value();
    }
    flatMap(fn) {
        return this.map(fn).join();
    }
}

const fs = require('fs');
const path = require('path')

var readFile = function(filename) {
  return new IO(function() {
    return fs.readFileSync(filename, 'utf-8');
  });
};

var print = function(x) {
  return new IO(function() {
    console.log(x);
    return x;
  });
}

// const fileName = path.resolve(__dirname, 'package.json')
// let r = readFile(fileName) .map(fp.toUpper) .flatMap(print) .join()

// 下面这行代码，直接点击右上角运行，会找不到文件。
// 需在终端。cd到 fed-e../code路径，运行node test.js，才能得到正确的结果
let r = readFile('package.json') .map(fp.toUpper) .flatMap(print) .join()

console.log("r", r)